﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 打开
{
    class ButtonQuick : Button
    {

        #region 静态变量

        private static ButtonQuick[] buttonQuick = new ButtonQuick[] { };

        /// <summary>提示框</summary>
        private static ToolTip tt = new ToolTip();

        /// <summary>记录按下计时时钟</summary>
        private static Timer timer = new Timer();

        /// <summary>消息框</summary>
        private static MessegeForm msg = new MessegeForm();

        /// <summary>按钮菜单各项文本</summary>
        private static string[] TSitem = new string[] { "项目路径", "运行项目", "提取图标", "更改项目", "删除项目" };

        /// <summary>滑条值</summary>
        private static int SliderValue = 0;

        #endregion

        #region 公共变量

        /// <summary>按钮参数</summary>
        public DataManager.ButtonData BtnData;

        #endregion

        #region 私有变量

        /// <summary>按钮身份</summary>
        private int number;

        /// <summary>按钮区域</summary>
        private Rectangle rect { get; set; }

        /// <summary>鼠标点击位置</summary>
        private Point pointClick;

        /// <summary>是否左键按下</summary>
        private bool isClicked = false;

        /// <summary>按下计时开关</summary>
        private bool TimerSwitch = false;

        /// <summary>记录左键按下时刻</summary>
        private DateTime clickTime = new DateTime();

        /// <summary>按钮右键菜单</summary>
        private ContextMenuStrip cms = new ContextMenuStrip();

        /// <summary>按钮右键菜单选项</summary>
        private ToolStripMenuItem[] tsmi = new ToolStripMenuItem[5];

        #endregion

        /// <summary>按钮构造函数</summary>
        public ButtonQuick(Point location, Size size, DataManager.ButtonData btnData)
        {
            initSetting(location,size);
            initBtnData(btnData);
            initCMS();
        }

        /// <summary>初始化按钮设置</summary>
        private void initSetting(Point location, Size size)
        {
            Location = location;
            Size = size;

            BackgroundImageLayout = ImageLayout.Zoom;
            AllowDrop = true;
            Visible = true;
            Enabled = true;

            timer.Interval = 2000;
            timer.Enabled = false;
            timer.Tick += new EventHandler(timer_tick);

            number = buttonQuick.Length;
            rect = new Rectangle(Location, Size);

            List<ButtonQuick> bq = buttonQuick.ToList();
            bq.Add(this);
            buttonQuick = bq.ToArray();

        }

        /// <summary>初始化按钮数据</summary>
        private void initBtnData(DataManager.ButtonData data)
        {
            BtnData = data;
            BackgroundImage = data.Icon;
            DataManager.buttonData[SliderValue, number] = data;
        }

        /// <summary>初始化按钮菜单</summary>
        private void initCMS()
        {

            /// <summary>添加右键菜单到按钮</summary>
            ContextMenuStrip = cms;

            foreach (var str in TSitem)
            {

                //获取str在数组中的索引
                int index = TSitem.ToList().IndexOf(str);

                tsmi[index] = new ToolStripMenuItem();
                tsmi[index].Text = TSitem[index];
                cms.Items.Add(tsmi[index]);

            }

            //委托菜单单击事件
            tsmi[0].Click += new EventHandler(项目路径);
            tsmi[1].Click += new EventHandler(运行项目);
            tsmi[2].Click += new EventHandler(提取图标);
            tsmi[3].Click += new EventHandler(更改项目);
            tsmi[4].Click += new EventHandler(删除项目);

        }

       

        private void 项目路径(object sender,EventArgs e)
        {
            Console.WriteLine("项目路径");
            OpenAndSelect(BtnData.Path);
        }

        private void 运行项目(object sender, EventArgs e)
        {
            Console.WriteLine("运行项目");
            DoubleClick_Dosomething();
        }

        private void 提取图标(object sender, EventArgs e)
        {
            Console.WriteLine("提取目标");

            string filepath_提取图标;
            
            msg.createForm("是否提取到源文件夹???", MessegeForm.ButtonKind.是否钮);

            if (msg.DialogResult == DialogResult.Yes)
            {
                filepath_提取图标 = BtnData.Path.Remove(BtnData.Path.LastIndexOf(".")) + ".ico";
            }
            else if (msg.DialogResult == DialogResult.No)
            {
                filepath_提取图标 = AppDomain.CurrentDomain.BaseDirectory + System.IO.Path.GetFileName(BtnData.Path.Remove(BtnData.Path.LastIndexOf("."))) + ".ico";
            }
            else
            {
                Console.WriteLine("取消提取图标操作...");
                return;
            }
            Console.WriteLine(filepath_提取图标);
            Bitmap b = new Bitmap(BackgroundImage.GetThumbnailImage(32, 32, null, new IntPtr()));
            b.Save(filepath_提取图标, System.Drawing.Imaging.ImageFormat.Icon);
            OpenAndSelect(filepath_提取图标);
        }

        private void 更改项目(object sender, EventArgs e)
        {
            Console.WriteLine("更改项目");
            msg.createForm("直接拖拽文件到按钮上即可");
        }

        private void 删除项目(object sender, EventArgs e)
        {
            Console.WriteLine("删除项目");
            msg.createForm("是否删除此项目?!",MessegeForm.ButtonKind.是否钮);

            if (msg.DialogResult == DialogResult.Yes)
            {
                Console.WriteLine("删除项目");

                //初始化按钮数据
                initBtnData(DataManager.ButtonData.None);

            }
            else
            {
                Console.WriteLine("不删除项目");
                return;
            }
        }

        /// <summary>打开文件所在文件夹并选择此文件</summary>
        /// <param name="path">路径</param>
        public void OpenAndSelect(string path)
        {
            ProcessStartInfo psi = new ProcessStartInfo("Explorer.exe");
            psi.Arguments = "/e,/select," + path;
            Process.Start(psi);
        }

        #region 按钮基本事件代码

        /// <summary>鼠标进入按钮事件</summary>
        protected override void OnMouseEnter(EventArgs e)
        {
            tt.SetToolTip(this, BtnData.Path);
            //Console.Write("鼠标进入" + Handle + "||" + Tag + "\n");
        }

        /// <summary>鼠标弹起按钮事件</summary>
        protected override void OnMouseUp(MouseEventArgs e)
        {

            //右键判断
            if (e.Button == MouseButtons.Right)   
            {
                RightClick_Dosomething();
                return;
            }

            //双击判断
            if (isClicked && e.Button == MouseButtons.Left)  
            {
                isClicked = false;
                TimeSpan span = DateTime.Now - clickTime;
                if (span.Milliseconds < SystemInformation.DoubleClickTime && span.Seconds < 1)
                {
                    Cursor.Current = Cursors.WaitCursor;
                    DoubleClick_Dosomething();
                }
            }
            else if (e.Button == MouseButtons.Left)
            {
                isClicked = true;
                clickTime = DateTime.Now;
            }

            //移动判断
            if (TimerSwitch == true)   
            {
                //如果移动过按钮回原位置
                Location = rect.Location;
                
                
                for (int i = 0; i < buttonQuick.Length; i++)
                {
                    //判断按钮移动到哪个按钮上了
                    if (buttonQuick[i].rect.Contains(Parent.PointToClient(MousePosition)))
                    {
                        
                        if (number != i)
                        {              
                            ExchangeEvent(number, i);
                        }

                        break;
                    }
                }
                
            }
            TimerSwitch = false;
            timer.Enabled = false;
        }

        /// <summary>鼠标按下按钮事件</summary>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Button == MouseButtons.Left)
            {
                pointClick = e.Location;
                timer.Enabled = true;
                BringToFront();
            }
        }

        /// <summary>鼠标移动事件</summary>
        protected override void OnMouseMove(MouseEventArgs e)
        {

            if (TimerSwitch == true && e.Button == MouseButtons.Left)
            {
                Left += e.Location.X - pointClick.X;
                Top += e.Location.Y - pointClick.Y;
            }
            else
            {
                TimerSwitch = false;
            }

        }

        /// <summary>鼠标拖进事件</summary>
        protected override void OnDragEnter(DragEventArgs e)
        {

            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Link; //重要代码：表明是链接类型的数据，比如文件路径
            }
                
            else e.Effect = DragDropEffects.None;
        }

        /// <summary>鼠标拖拽事件</summary>
        protected override void OnDragDrop(DragEventArgs e)
        {
            base.OnDragDrop(e);

            if (BtnData.buttonKind != DataManager.ButtonData.ButtonKind.None)
            {
                msg.createForm("是否更改此项目", MessegeForm.ButtonKind.是否钮);
                if (msg.DialogResult != DialogResult.Yes)
                {
                    return;
                }
            }

            string path = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();//获取文件路径

            if (DataManager.GetFilePath(path) == "")
            {
                msg.createForm("文件路径无效！！！");
                return;
            }

            //按钮数据刷新
            initBtnData(new DataManager.ButtonData(path));
        }

        /// <summary>鼠标按下时钟周期事件</summary>
        private void timer_tick(object sender,EventArgs e)
        {
            if (TimerSwitch == false && new Rectangle(new Point(0,0),Size).Contains(PointToClient(MousePosition)))
            {
                TimerSwitch = true;
                System.Media.SystemSounds.Beep.Play();
                timer.Enabled = false;
            }
        }

        #endregion

        #region 按钮高级事件代码

        /// <summary>双击事件</summary>
        private void DoubleClick_Dosomething()
        {
            
            ProcessStartInfo psi = new ProcessStartInfo("Explorer.exe");

            if (BtnData.buttonKind == DataManager.ButtonData.ButtonKind.File || BtnData.buttonKind == DataManager.ButtonData.ButtonKind.Directory)
            {
                psi.FileName = BtnData.Path;
                if (BtnData.buttonKind == DataManager.ButtonData.ButtonKind.File)
                {
                    psi.WorkingDirectory = psi.FileName.Substring(0, psi.FileName.LastIndexOf(@"\"));
                }
                try
                {
                    Process.Start(psi);
                }
                catch (Win32Exception)
                {
                    msg.createForm("这不是一个有效的可执行文件！！！");
                }
            }
            else
            {
                更改项目(null,EventArgs.Empty);
            }
        }

        /// <summary>右键单击事件</summary>
        private void RightClick_Dosomething()
        {

            if (BtnData.buttonKind == DataManager.ButtonData.ButtonKind.File || BtnData.buttonKind == DataManager.ButtonData.ButtonKind.Directory)
            {

                tsmi[0].Visible = true;
                tsmi[1].Visible = true;
                tsmi[3].Visible = true;
                if (BtnData.buttonKind == DataManager.ButtonData.ButtonKind.File)
                    tsmi[2].Visible = true;
                else
                    tsmi[2].Visible = false;
            }
            else
            {
                // 项目路径ToolStripMenuItem.Text = "项目路径 ";
                tsmi[0].Visible = false;
                tsmi[1].Visible = false;
                tsmi[2].Visible = false;
                tsmi[4].Visible = false;
            }

        }

        /// <summary>按钮交换事件</summary>
        /// <param name="e">移动按钮</param>
        /// <param name="s">交换按钮</param>
        private void ExchangeEvent(int e, int s)
        {
            Console.WriteLine("按钮{0}和按钮{1}交换", e, s);

            //按钮数据交换
            DataManager.ButtonData bd = DataManager.buttonData[SliderValue, e];
            DataManager.buttonData[SliderValue, e] = DataManager.buttonData[SliderValue, s];
            DataManager.buttonData[SliderValue, s] = bd;


            //按钮初始化
            buttonQuick[e].initBtnData(DataManager.buttonData[SliderValue, e]);
            buttonQuick[s].initBtnData(DataManager.buttonData[SliderValue, s]);

        }

        #endregion

        /// <summary>滑动类型</summary>
        public enum SliderType
        {
            Add,
            Reduce
        }

        /// <summary>按钮滑动事件</summary>
        /// <param name="st">滑动类型</param>
        /// <param name="value">滑条数值</param>
        public static void Slide(SliderType st, int value)
        {
            SliderValue =  value - 1;
            
            //如果滑条类型是增加 按钮从右往左移动 反之亦然
            if (st == SliderType.Add)
            {
                while (buttonQuick[1].Left > buttonQuick[0].rect.X)
                {
                    for (int i = 0; i < 15; i++)
                    {
                        buttonQuick[i].Left -= 5;
                    }
                }
            }
            else
            {
                while (buttonQuick[1].Left < buttonQuick[2].rect.X)
                {
                    for (int i = 0; i < 15; i++)
                    {
                        buttonQuick[i].Left += 5;
                    }
                }
            }

            for (int i = 0; i < 15; i++)
            {
                //滑动效果完成后按钮回原位置
                buttonQuick[i].Left = buttonQuick[i].rect.Left;
                //按钮数据刷新
                buttonQuick[i].initBtnData(DataManager.buttonData[SliderValue, i]);
            }

        }
        /// <summary>按钮滑动事件</summary>
        /// <param name="sign">滑动符号</param>
        /// <param name="value">滑条数值</param>
        public static void Slide(int sign, int value)
        {
            SliderValue = value - 1;

            //如果符号标志大于0 按钮从右往左移动 反之亦然
            if (sign > 0)
            {
                while (buttonQuick[1].Left > buttonQuick[0].rect.X)
                {
                    for (int i = 0; i < 15; i++)
                    {
                        buttonQuick[i].Left -= 5;
                    }
                }
            }
            else
            {
                while (buttonQuick[1].Left < buttonQuick[2].rect.X)
                {
                    for (int i = 0; i < 15; i++)
                    {
                        buttonQuick[i].Left += 5;
                    }
                }
            }

            for (int i = 0; i < 15; i++)
            {
                //滑动效果完成后按钮回原位置
                buttonQuick[i].Left = buttonQuick[i].rect.Left;
                //按钮数据刷新
                buttonQuick[i].initBtnData(DataManager.buttonData[SliderValue, i]);
            }

        }

    }

}
